'use strict'

import { app, shell, ipcMain, protocol, BrowserWindow, Menu } from 'electron'
import mainWindow from './background/mainWindow.js' // 主窗口
import subWindow from './background/subWindow.js' // 子窗口
// import updateWindow from './background/updateWindow.js' // 更新窗口

const path = require('path')
const cp = require('child_process')
const JSZip = require('jszip')

const electronSettingsPack = require('./assets/js/electronSettingsPack')
const customProtocol = require('./background/customProtocol.js')
const singleInstanceLock = require('./background/singleInstanceLock.js')
const shortcut = require('./background/shortcut.js')
const menu = require('./background/menu.js')
const flashPlugin = require('./background/flashPlugin.js')
const sharedObject = require('./background/sharedObject.js') // 初始化共享数据
const isDevelopment = process.env.NODE_ENV !== 'production'

// 注册全局变量
global.sharedObject = sharedObject
global.wwwroot = {path: __dirname}
global.cookie = ''
// 禁止多开
singleInstanceLock()
// 自定义协议
customProtocol()
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: { secure: true, standard: true } }
])
// 加载flash插件
flashPlugin()

// 测试：开启websocket服务
sharedObject.wsServer.start()
subWindow.init()

/**
 * 为了解决以下警告
 * (electron) The default value of app.allowRendererProcessReuse is deprecated, it is currently "false".  It will change to be "true" in Electron 9.
 * For more information please check https://github.com/electron/electron/issues/18397
 */
// app.allowRendererProcessReuse = true

/**
 * 为了解决以下错误
 * Uncaught Error: Loading non-context-aware native module in renderer:
 */
app.allowRendererProcessReuse = false

// 禁用硬件加速，避免部分机器黑屏
// app.disableHardwareAcceleration()

// 忽略证书相关错误
app.commandLine.appendSwitch('ignore-certificate-errors')

app.on('ready', () => {
  shortcut.regConsole('Command+Control+Alt+F5') // 注册控制台快捷键
  menu(Menu) // 设置菜单
  // updateWindow.init()
  mainWindow.init()
})

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    mainWindow.init()
  }
})

app.on('web-contents-created', (e, webContents) => {
  webContents.on('new-window', (event, url) => {
    event.preventDefault()
    if (url !== 'about:blank') {
      shell.openExternal(url)
    }
  })
})

app.on('window-all-closed', () => {
  let allWindows = BrowserWindow.getAllWindows()
  if (allWindows.length === 0 ) app.exit(1)
  console.log('window-all-closed:', allWindows.length)
})

// 程序退出前关闭服务
app.on('before-quit', () => {
  global.sharedObject.udpServer && global.sharedObject.udpServer.stop()
  global.sharedObject.wsServer && global.sharedObject.wsServer.stop()
  global.sharedObject.httpServer && global.sharedObject.httpServer.stop()
})

// 启动主窗体
ipcMain.on('create-main', (event, arg) => {
  global.wwwroot.path = arg.path || __dirname
  if (arg.version) {
    electronSettingsPack.setVal('version', 'smallVersion', arg.version)
    // 更新全局变量
    global.sharedObject.version = arg.version
  }
  mainWindow.init()
  // updateWindow.close()
})

// 启动更新窗体
ipcMain.on('create-update', () => {
  // updateWindow.init()
  mainWindow.close()
  subWindow.closeAll()
})

// 解压最新的下载包文件夹
ipcMain.on('update-main-unzip', (event, arg) => {
  if (!global.sharedObject.jstoolsNode) return
  let unzipFile = global.sharedObject.jstoolsNode.unzipFile
  let {from, to, callback} = arg || {}
  unzipFile({ from, to, JSZip }).then(() => {
    callback && callback()
  })
})

// 主窗体自我更新
ipcMain.on('update-main', (event, arg) => {
  global.wwwroot.path = arg.newVersionPath || __dirname
  if (arg.version) electronSettingsPack.setVal('version', 'smallVersion', arg.version)
  app.relaunch()
  app.exit(0)
})

/**
 * 更新主窗口大小及关闭状态
 * @param {Number} arg/winId 窗口id
 * @param {String} arg/eventType 事件类型
 */
ipcMain.on('updateWindowStatus', (event, arg) => {
  let {eventType, winId} = arg || {}
  let allWindows = BrowserWindow.getAllWindows()
  let targetWindow = (allWindows.filter(win => win.webContents.id === winId))[0]
  if (!targetWindow) return
  let resizable = targetWindow.resizable
  if (targetWindow && !targetWindow.isDestroyed()) {
    if (eventType === 'minimize') {
      targetWindow.minimize()
    } else if (eventType === 'fullscreen') {
      if (!resizable) targetWindow.setResizable(true)
      if (process.platform === 'darwin') {
        targetWindow.setSimpleFullScreen(true)
      } else {
        targetWindow.setFullScreen(true)
      }
      if (!resizable) targetWindow.setResizable(false)
    } else if (eventType === 'restore') {
      if (!resizable) targetWindow.setResizable(true)
      if (process.platform === 'darwin') {
        targetWindow.setSimpleFullScreen(false)
      } else {
        targetWindow.setFullScreen(false)
      }
      if (!resizable) targetWindow.setResizable(false)
    } else if (eventType === 'close') {
      let mainId = mainWindow.getId()
      targetWindow.destroy()
      targetWindow = null
      if (mainId === winId) app.exit(1)
    }
  }
})

// 重启程序&安装更新包
ipcMain.on('update-app', (event, execPath) => {
  if (process.platform === 'win32') {
    // 重新启动项目
    app.relaunch({ execPath })
    app.exit(2)
  } else if (process.platform === 'darwin') {
    // closeAllWindow()
    // 方案一（卸载dmg会报错）
    // // 挂载dmg新包
    // cp.execSync(`hdiutil attach '${execPath}' -nobrowse`, {
    //     stdio: ['ignore', 'ignore', 'ignore']
    // })
    // // 覆盖原app
    // let appName = global.sharedObject.appName || 'XUE5HEN'
    // cp.execSync(`rm -rf '/Applications/${appName}.app' && cp -R '/Volumes/${appName}/${appName}.app' '/Applications/${appName}.app'`)
    // // 卸载挂载的dmg
    // cp.execSync(`hdiutil eject '/Volumes/${appName}/'`, {
    //     stdio: ['ignore', 'ignore', 'ignore']
    // })
    // app.relaunch()
    // app.quit()

    // 方案二
    let tempDataPath = global.sharedObject.tempDataPath || app.getPath('temp')
    let fileName = path.basename(execPath)
    let tempFilePath = path.join(tempDataPath, fileName)
    cp.execSync(`cp -R '${execPath}' '${tempFilePath}'`)
    cp.spawnSync('open', [tempFilePath])
    app.exit(1)
  }
})

// 退出程序
ipcMain.on('quit-app', () => {
  app.exit(1)
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', (data) => {
      if (data === 'graceful-exit') {
        app.quit()
      }
    })
  } else {
    process.on('SIGTERM', () => {
      app.quit()
    })
  }
}
